package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tbit.uqbike.object.pojo.CardAccountBound;
import com.tbit.uqbike.object.pojo.dto.CardAccountBoundDTO;
import com.tbit.uqbike.object.pojo.vo.CardAccountBoundVO;
import com.tbit.uqbike.object.pojo.vo.CardAccountIdAndNameVO;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.service.business.CardAccountBoundService;
import com.tbit.uqbike.webmanager.dao.core.CardAccountBoundDao;
import com.tbit.uqbike.webmanager.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * 区域共享配置接口实现
 *
 * @Author:BUGTian
 * @DATE: 2023/1/5
 */
@Service
public class CardAccountBoundServiceImpl extends ServiceImpl<CardAccountBoundDao, CardAccountBound> implements CardAccountBoundService {
    @Autowired
    private CardAccountBoundDao cardAccountBoundDao;

    @Override
    public List<CardAccountBoundVO> queryList(Integer brandId, Integer accountId, Integer cardType) {
        List<CardAccountBoundVO> list = cardAccountBoundDao.queryList(brandId, accountId, cardType);
        for (CardAccountBoundVO cardAccountBoundVO : list) {
            if (StringUtils.isEmpty(cardAccountBoundVO.getAccountIds())) {
                continue;
            }
            cardAccountBoundVO.setAccountName(cardAccountBoundDao.queryAccountName(cardAccountBoundVO.getAccountIds()));
        }
        return list;
    }

    @Override
    public Result<String> addConfig(Integer brandId, String configName, Integer cardType) {
        if (count(new QueryWrapper<CardAccountBound>().eq("brandId", brandId).eq("configName", configName)) > 0) {
            return Result.error("配置名称已存在");
        }
        save(new CardAccountBound(null, configName, cardType, brandId, null, new Date()));
        return Result.success();
    }

    @Override
    public Result<String> updateConfig(Long id, String configName) {
        CardAccountBound cardAccountBound = getById(id);
        if (cardAccountBound == null) {
            return Result.error("配置不存在");
        }
        if (count(new QueryWrapper<CardAccountBound>().eq("brandId", cardAccountBound.getBrandId()).eq("configName", configName).ne("id", id)) > 0) {
            return Result.error("配置名称已存在");
        }
        updateById(cardAccountBound.setConfigName(configName).setUpdateTime(new Date()));
        return Result.success();
    }

    @Override
    public Result<List<String>> boundCheck(CardAccountBoundDTO cardAccountBoundDTO) {
        CardAccountBound cardAccountBound = getById(cardAccountBoundDTO.getId());
        if (cardAccountBound == null) {
            return Result.error("配置不存在");
        }
        getDuplicateRemovalAccountId(cardAccountBoundDTO, cardAccountBound);
        //获取已绑定区域id
        List<Integer> accountIdList = cardAccountBoundDTO.getAccountIdList();
        if (accountIdList.size() < 2) {
            return Result.error("请选择互通的区域");
        }
        List<Integer> isBoundAccountId = getIsBoundAccountId(cardAccountBound.getId(), cardAccountBound.getBrandId(), accountIdList, cardAccountBound.getCardType(), false);
        List<String> isBoundAccountName = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(isBoundAccountId)) {
            //已绑定区域名称
            isBoundAccountName = cardAccountBoundDao.queryAccountNameByIdList(isBoundAccountId);
        }
        return Result.success(isBoundAccountName);
    }

    @Override
    public Result<String> bound(CardAccountBoundDTO cardAccountBoundDTO) {
        CardAccountBound cardAccountBound = getById(cardAccountBoundDTO.getId());
        if (cardAccountBound == null) {
            return Result.error("配置不存在");
        }
        getDuplicateRemovalAccountId(cardAccountBoundDTO, cardAccountBound);
        List<Integer> accountIdList = cardAccountBoundDTO.getAccountIdList();
        if (accountIdList.size() < 2) {
            return Result.error("请选择互通的区域");
        }
        getIsBoundAccountId(cardAccountBound.getId(), cardAccountBound.getBrandId(), accountIdList, cardAccountBound.getCardType(), true);
        updateById(cardAccountBound.setAccountIds(cardAccountBoundDTO.getAccountIds()).setUpdateTime(new Date()));
        return Result.success();
    }

    @Override
    public Result<List<CardAccountIdAndNameVO>> getCardAccountIdAndName(Long id) {
        List<CardAccountIdAndNameVO> list = new LinkedList<>();
        CardAccountBound cardAccountBound = getById(id);
        if (cardAccountBound == null) {
            return Result.error("配置不存在");
        }
        if (StringUtils.isNotEmpty(cardAccountBound.getAccountIds())) {
            for (Integer accountId : cardAccountBound.getAccountIdList()) {
                list.add(new CardAccountIdAndNameVO(accountId, cardAccountBoundDao.queryAccountName(accountId.toString())));
            }
        }
        return Result.success(list);
    }

    @Override
    public Result<String> delOneAccountBound(Long id, Integer accountId) {
        CardAccountBound cardAccountBound = getById(id);
        if (cardAccountBound == null) {
            return Result.error("配置不存在");
        }
        List<Integer> accountIdList = cardAccountBound.getAccountIdList();
        accountIdList.removeIf(a -> a.equals(accountId));
        String accountIds = "";
        if (accountIdList.size() >= 2) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Integer integer : accountIdList) {
                stringBuilder.append(integer);
                stringBuilder.append(",");
            }
            String s = stringBuilder.toString();
            accountIds = s.substring(0, s.length() - 1);
        }
        updateById(cardAccountBound.setAccountIds(accountIds).setUpdateTime(new Date()));
        return Result.success();
    }

    /**
     * 获取去重后总的绑定区域
     *
     * @param cardAccountBoundDTO 需要新增的绑定区域信息
     * @param cardAccountBound    原有的绑定区域信息
     */
    private void getDuplicateRemovalAccountId(CardAccountBoundDTO cardAccountBoundDTO, CardAccountBound cardAccountBound) {
        List<Integer> accountIdList = cardAccountBound.getAccountIdList();
        String accountIds = cardAccountBound.getAccountIds();
        for (Integer accountId : cardAccountBoundDTO.getAccountIdList()) {
            if (!accountIdList.contains(accountId)) {
                accountIdList.add(accountId);
                if (StringUtils.isEmpty(accountIds)) {
                    accountIds = accountId.toString();
                } else {
                    accountIds = accountIds + "," + accountId.toString();
                }
            }
        }
        //去重后实际总绑定的区域
        cardAccountBoundDTO.setAccountIds(accountIds);
    }

    /**
     * 获取/删除 品牌内相同卡类型已绑定区域id
     *
     * @param id            当前配置id
     * @param brandId       品牌id
     * @param accountIdList 区域id列表
     * @param cardType      卡类型
     * @param isDel         是否删除已绑定区域
     * @return
     */
    private List<Integer> getIsBoundAccountId(Long id, Integer brandId, List<Integer> accountIdList, Integer cardType, Boolean isDel) {
        List<Integer> isBoundAccountId = new ArrayList<>();
        for (Integer accountId : accountIdList) {
            //该记录只会有一条
            List<CardAccountBoundVO> list = cardAccountBoundDao.queryList(brandId, accountId, cardType);
            //忽略当前配置的绑定关系
            if (CollectionUtil.isNotEmpty(list) && !list.get(0).getId().equals(id)) {
                if (isDel) {
                    //从已绑定区域中删除
                    CardAccountBoundVO cardAccountBoundVO = list.get(0);
                    List<Integer> accountIdListInDb = cardAccountBoundVO.getAccountIdList();
                    accountIdListInDb.removeIf(a -> a.equals(accountId));
                    String accountIds = "";
                    if (accountIdListInDb.size() >= 2) {
                        StringBuilder stringBuilder = new StringBuilder();
                        for (Integer integer : accountIdListInDb) {
                            stringBuilder.append(integer);
                            stringBuilder.append(",");
                        }
                        String s = stringBuilder.toString();
                        accountIds = s.substring(0, s.length() - 1);
                    }
                    updateById(cardAccountBoundVO.setAccountIds(accountIds));
                }
                isBoundAccountId.add(accountId);
            }
        }
        return isBoundAccountId;
    }
}
